<?php
/**
 * 知识网盘控制器 - 包含笔记功能
 */

declare (strict_types = 1);

namespace app\controller\disk;

use app\BaseController;
use think\facade\Db;
use think\facade\Request;
use think\facade\Filesystem;
use think\facade\Log; // 添加Log类的导入
use think\Request as RequestObject; // 导入Request对象用于依赖注入
use app\model\oa\Disk;
use app\model\admin\User; // 修改为使用User模型
use app\common\FileUploadConfig; // 导入全局文件上传配置类

// 定义目录分隔符常量
if (!defined('DS')) {
    define('DS', DIRECTORY_SEPARATOR);
}

class Index extends BaseController
{
    /**
     * 无需登录的方法
     * @var array
     */
    protected $noNeedLogin = ['detail', 'view', 'viewArticle', 'uploadAttachment', 'downloadAttachment'];
    
    /**
     * 重写checkAuth方法，允许无需登录访问的方法
     */
    protected function checkAuth()
    {
        // 调用父类的checkAuth方法
        return parent::checkAuth();
    }
    
    /**
     * 笔记列表
     */
    public function list()
    {
        $param = Request::param();
        $type = $param['type'] ?? 'personal'; // personal: 个人文件, shared: 共享文件, trash: 回收站
        $page = $param['page'] ?? 1;
        $limit = $param['limit'] ?? 15;
        $keywords = $param['keywords'] ?? '';
        
        try {
            $userId = $this->getCurrentUserId();
            $departmentId = $this->getCurrentUserDepartmentId();
            
            // 构建查询条件
            $where = [];
            
            // 根据类型设置不同的查询条件
            if ($type === 'personal') {
                // 个人文件：只显示当前用户创建的笔记
                $where[] = ['a.admin_id', '=', $userId];
                $where[] = ['a.delete_time', '=', 0];
            } elseif ($type === 'shared') {
                // 共享文件：显示分享给当前用户或其部门的笔记
                $where[] = ['a.delete_time', '=', 0];
                $where[] = ['a.admin_id', '<>', $userId]; // 排除自己的笔记
                
                // 由于article_access表不存在，暂时使用其他方式实现共享逻辑
                // 这里可以扩展article表，添加shared_users和shared_departments字段
                // 或者创建新的article_share表
                // 暂时注释掉状态字段判断，因为表中不存在该字段
                // $where[] = ['a.status', '=', 1]; // 暂时使用状态字段判断是否共享
            } elseif ($type === 'trash') {
                // 回收站：只显示当前用户删除的笔记
                $where[] = ['a.admin_id', '=', $userId];
                $where[] = ['a.delete_time', '>', 0];
            }
            
            // 添加关键词搜索
            if (!empty($keywords)) {
                $where[] = [
                    ['a.name', 'like', '%' . trim($keywords) . '%'],
                    ['a.content', 'like', '%' . trim($keywords) . '%'],
                    'OR'
                ];
            }
            
            // 查询笔记列表
            $query = Db::name('article')
                ->alias('a')
                ->join('admin ad', 'a.admin_id = ad.id', 'LEFT')
                ->field('a.id, a.admin_id, a.name as title, a.content, a.create_time, a.update_time, a.delete_time, a.file_ids, ad.name as author, ad.did as author_dept_id');
            
            // 应用查询条件
            foreach ($where as $condition) {
                if (is_array($condition) && count($condition) === 3) {
                    $query->where($condition[0], $condition[1], $condition[2]);
                } elseif (is_array($condition) && count($condition) === 2 && $condition[1] === 'OR') {
                    // 处理OR条件
                    $query->where(function($query) use ($condition) {
                        $query->whereLike($condition[0][0], $condition[0][1])
                              ->whereOr($condition[0][2], $condition[0][3]);
                    });
                }
            }
            
            // 排序
            if ($type === 'trash') {
                $query->order('a.delete_time', 'desc');
            } else {
                $query->order('a.update_time', 'desc');
            }
            
            // 分页查询
            $list = $query->paginate([
                'list_rows' => $limit,
                'page' => $page
            ]);
            
            // 处理返回数据
            $items = $list->items();
            foreach ($items as &$item) {
                // 格式化时间
                $item['create_time'] = date('Y-m-d H:i', $item['create_time']);
                $item['update_time'] = date('Y-m-d H:i', $item['update_time']);
                if ($item['delete_time'] > 0) {
                    $item['delete_time'] = date('Y-m-d H:i', $item['delete_time']);
                } else {
                    $item['delete_time'] = '';
                }
                
                // 获取附件信息
                $attachments = [];
                if (!empty($item['file_ids'])) {
                    $fileIds = array_filter(explode(',', $item['file_ids']));
                    if (!empty($fileIds)) {
                        $attachments = Db::name('file')
                            ->where('id', 'in', $fileIds)
                            ->where('delete_time', '=', 0)
                            ->field('id, name, filename, filesize, fileext, create_time')
                            ->select()
                            ->toArray();
                        
                        // 格式化附件信息
                        foreach ($attachments as &$attachment) {
                            $attachment['upload_time'] = date('Y-m-d H:i', $attachment['create_time']);
                            $attachment['filesize'] = $this->formatFileSize($attachment['filesize']);
                        }
                    }
                }
                $item['attachments'] = $attachments;
                
                // 判断权限
                $item['can_edit'] = ($item['admin_id'] == $userId) && ($item['delete_time'] == 0);
                $item['can_delete'] = ($item['admin_id'] == $userId) && ($item['delete_time'] == 0);
                $item['can_share'] = ($item['admin_id'] == $userId) && ($item['delete_time'] == 0);
                $item['can_restore'] = ($item['admin_id'] == $userId) && ($item['delete_time'] > 0);
                
                // 设置共享状态 - 由于表中没有status字段，暂时设置为false
                $item['is_shared'] = false; // ($item['status'] == 1) && ($item['delete_time'] == 0);
            }
            
            return json([
                'code' => 0,
                'msg' => 'success',
                'data' => [
                    'list' => $items,
                    'total' => $list->total(),
                    'page' => $page,
                    'limit' => $limit
                ]
            ]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '获取笔记列表失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 格式化文件大小
     */
    private function formatFileSize($size)
    {
        if ($size >= 1073741824) {
            return round($size / 1073741824, 2) . ' GB';
        } elseif ($size >= 1048576) {
            return round($size / 1048576, 2) . ' MB';
        } elseif ($size >= 1024) {
            return round($size / 1024, 2) . ' KB';
        } else {
            return $size . ' B';
        }
    }
    
    /**
     * 笔记详情
     */
    public function detail()
    {
        $id = Request::param('id');
        $type = Request::param('type', 'normal'); // normal: 正常笔记, trash: 回收站笔记
        
        if (empty($id)) {
            return json(['code' => 400, 'msg' => '笔记ID不能为空']);
        }
        
        try {
            $userId = $this->getCurrentUserId();
            
            // 构建查询条件
            $where = [['a.id', '=', $id]];
            
            // 根据类型设置不同的查询条件
            if ($type === 'trash') {
                // 回收站笔记：只显示当前用户删除的笔记
                $where[] = ['a.admin_id', '=', $userId];
                $where[] = ['a.delete_time', '>', 0];
            } else {
                // 正常笔记：只显示未删除的笔记
                $where[] = ['a.delete_time', '=', 0];
            }
            
            // 获取笔记详情
            $article = Db::name('article')
                ->alias('a')
                ->join('admin ad', 'a.admin_id = ad.id', 'LEFT')
                ->field('a.id, a.admin_id, a.name, a.content, a.create_time, a.update_time, a.delete_time, ad.name as author')
                ->where($where)
                ->find();
            
            if (!$article) {
                return json(['code' => 404, 'msg' => '笔记不存在或无权访问']);
            }
            
            // 格式化时间
            $article['create_time'] = date('Y-m-d H:i', $article['create_time']);
            $article['update_time'] = date('Y-m-d H:i', $article['update_time']);
            if ($article['delete_time'] > 0) {
                $article['delete_time'] = date('Y-m-d H:i', $article['delete_time']);
            } else {
                $article['delete_time'] = '';
            }
            
            // 暂时设置为未分享，因为article_access表不存在且表中没有status字段
            $article['is_shared'] = false; // ($article['status'] == 1) && ($article['delete_time'] == 0);
            $article['shared_users'] = [];
            $article['shared_departments'] = [];
            
            // 获取附件列表 - 与列表API保持一致，使用file_ids字段查询
            $attachments = [];
            $fileIds = Db::name('article')->where('id', '=', $id)->value('file_ids');
            if (!empty($fileIds)) {
                $fileIdArray = array_filter(explode(',', $fileIds));
                if (!empty($fileIdArray)) {
                    $attachments = Db::name('file')
                        ->where('id', 'in', $fileIdArray)
                        ->where('delete_time', '=', 0)
                        ->field('id, name, filename, filesize, fileext, create_time, filepath')
                        ->select()
                        ->toArray();
                    
                    // 格式化附件信息
                    foreach ($attachments as &$attachment) {
                        $attachment['upload_time'] = date('Y-m-d H:i', $attachment['create_time']);
                        $attachment['size'] = $this->formatFileSize($attachment['filesize']);
                        $attachment['ext'] = $attachment['fileext'];
                        unset($attachment['filesize'], $attachment['fileext']);
                    }
                }
            }
            
            $article['attachments'] = $attachments;
            
            // 判断权限
            $article['can_edit'] = ($article['admin_id'] == $userId) && ($article['delete_time'] == 0);
            $article['can_delete'] = ($article['admin_id'] == $userId) && ($article['delete_time'] == 0);
            $article['can_share'] = ($article['admin_id'] == $userId) && ($article['delete_time'] == 0);
            $article['can_restore'] = ($article['admin_id'] == $userId) && ($article['delete_time'] > 0);
            
            return json(['code' => 0, 'msg' => 'success', 'data' => $article]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '获取笔记详情失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 新建笔记
     */
    public function create()
    {
        // 获取原始输入数据
        $rawInput = file_get_contents('php://input');
        $param = [];
        
        // 尝试解析JSON数据
        if (!empty($rawInput)) {
            $jsonParam = json_decode($rawInput, true);
            if (is_array($jsonParam)) {
                $param = $jsonParam;
            }
        }
        
        // 合并URL参数和表单参数
        $param = array_merge($param, Request::param());
        $user_id = $this->getCurrentUserId(); // 获取当前登录用户ID
        
        if (empty($param)) {
            return json(['code' => 400, 'msg' => '参数不能为空']);
        }
        
        // 支持title和name两个字段名
        $title = $param['title'] ?? $param['name'] ?? '';
        if (empty($title)) {
            return json(['code' => 400, 'msg' => '笔记标题不能为空']);
        }
        
        // 支持content字段，允许内容为空
        $content = $param['content'] ?? '';
        // 如果内容为空，提供默认值
        if (empty($content)) {
            $content = '<p>暂无内容</p>';
        }
        
        try {
            // 开启事务
            Db::startTrans();
            
            try {
                // 插入笔记
                $articleData = [
                    'name' => $title,
                    'content' => $content,
                    'admin_id' => $user_id,
                    'create_time' => time(),
                    'update_time' => time()
                ];
                
                $articleId = Db::name('article')->insertGetId($articleData);
                
                // 处理附件关联
                $fileIds = $param['file_ids'] ?? '';
                if (!empty($fileIds)) {
                    $fileIdArray = array_filter(explode(',', $fileIds));
                    
                    // 更新文件记录，关联到笔记
                    foreach ($fileIdArray as $fileId) {
                        if (!empty($fileId)) {
                            // 检查文件是否存在
                            $fileExists = Db::name('file')->where('id', '=', (int)$fileId)->find();
                            if ($fileExists) {
                                Db::name('file')
                                    ->where('id', '=', (int)$fileId)
                                    ->update([
                                        'group_id' => $articleId,
                                        'create_time' => time()
                                    ]);
                            }
                        }
                    }
                    
                    // 更新article表的file_ids字段
                    Db::name('article')
                        ->where('id', '=', $articleId)
                        ->update(['file_ids' => $fileIds]);
                }
                
                // 提交事务
                Db::commit();
                
                // 记录操作日志
                $this->writeNoteLog($user_id, $articleId, 'create', '创建笔记');
                
                return json(['code' => 0, 'msg' => '创建笔记成功', 'data' => ['id' => $articleId]]);
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '创建笔记失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 更新笔记
     */
    public function update()
    {
        // 获取原始输入数据
        $rawInput = file_get_contents('php://input');
        $param = [];
        
        // 尝试解析JSON数据
        if (!empty($rawInput)) {
            $jsonParam = json_decode($rawInput, true);
            if (is_array($jsonParam)) {
                $param = $jsonParam;
            }
        }
        
        // 合并URL参数和表单参数
        $param = array_merge($param, Request::param());
        $user_id = $this->getCurrentUserId(); // 获取当前登录用户ID
        
        if (empty($param['id'])) {
            return json(['code' => 400, 'msg' => '笔记ID不能为空']);
        }
        
        // 支持title和name两个字段名
        $title = $param['title'] ?? $param['name'] ?? '';
        if (empty($title)) {
            return json(['code' => 400, 'msg' => '笔记标题不能为空']);
        }
        
        // 支持content字段，允许内容为空
        $content = $param['content'] ?? '';
        // 如果内容为空，提供默认值
        if (empty($content)) {
            $content = '<p>暂无内容</p>';
        }
        
        try {
            // 验证笔记是否存在
            $article = Db::name('article')
                ->where('id', '=', $param['id'])
                ->where('delete_time', '=', 0)
                ->find();
            
            if (!$article) {
                return json(['code' => 404, 'msg' => '笔记不存在或已删除']);
            }
            
            // 开启事务
            Db::startTrans();
            
            try {
                // 更新笔记
                $updateData = [
                    'name' => $title,
                    'content' => $content,
                    'update_time' => time()
                ];
                
                Db::name('article')
                    ->where('id', '=', $param['id'])
                    ->update($updateData);
                
                // 处理附件关联
                $fileIds = $param['file_ids'] ?? '';
                
                // 获取当前关联的文件ID列表
                $currentFileIds = Db::name('file')
                    ->where('group_id', '=', $param['id'])
                    ->where('module', '=', 'article')
                    ->column('id');
                
                // 解析新的文件ID列表
                $newFileIds = [];
                if (!empty($fileIds)) {
                    $newFileIds = array_filter(explode(',', $fileIds));
                }
                
                // 找出需要取消关联的文件ID
                $toUnlinkIds = array_diff($currentFileIds, $newFileIds);
                
                // 找出需要新增关联的文件ID
                $toLinkIds = array_diff($newFileIds, $currentFileIds);
                
                // 取消关联文件
                foreach ($toUnlinkIds as $fileId) {
                    Db::name('file')
                        ->where('id', '=', (int)$fileId)
                        ->update(['group_id' => 0]);
                }
                
                // 新增关联文件
                foreach ($toLinkIds as $fileId) {
                    Db::name('file')
                        ->where('id', '=', (int)$fileId)
                        ->update([
                            'group_id' => $param['id'],
                            'create_time' => time()
                        ]);
                }
                
                // 更新article表的file_ids字段
                Db::name('article')
                    ->where('id', '=', $param['id'])
                    ->update(['file_ids' => $fileIds]);
                
                // 提交事务
                Db::commit();
                
                // 记录操作日志
                $this->writeNoteLog($user_id, $param['id'], 'update', '更新笔记');
                
                return json(['code' => 0, 'msg' => '更新笔记成功']);
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '更新笔记失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 删除笔记
     */
    public function delete()
    {
        $id = Request::param('id');
        $user_id = $this->getCurrentUserId(); // 获取当前登录用户ID
        
        if (empty($id)) {
            return json(['code' => 400, 'msg' => '笔记ID不能为空']);
        }
        
        try {
            // 验证笔记是否存在
            $article = Db::name('article')
                ->where('id', '=', $id)
                ->where('delete_time', '=', 0)
                ->find();
            
            if (!$article) {
                return json(['code' => 404, 'msg' => '笔记不存在或已删除']);
            }
            
            // 开启事务
            Db::startTrans();
            
            try {
                // 软删除笔记
                Db::name('article')
                    ->where('id', '=', $id)
                    ->update(['delete_time' => time()]);
                
                // 暂时跳过删除访问权限记录，因为article_access表不存在
                // Db::name('article_access')
                //     ->where('article_id', '=', $id)
                //     ->delete();
                
                // 提交事务
                Db::commit();
                
                // 记录操作日志
                $this->writeNoteLog($user_id, $id, 'delete', '删除笔记');
                
                return json(['code' => 0, 'msg' => '删除笔记成功']);
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '删除笔记失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 上传附件
     */
    public function uploadAttachment(RequestObject $request)
    {
        try {
            // 验证请求 - 修复：使用注入的$request对象而不是静态调用
            if (!$request->file('file')) {
                return json(['code' => 400, 'msg' => '没有上传文件', 'data' => null, 'timestamp' => time()]);
            }

            $file = $request->file('file');
            
            // 验证文件
            if (!$file->isValid()) {
                return json(['code' => 400, 'msg' => '文件上传失败', 'data' => null, 'timestamp' => time()]);
            }

            // 获取当前用户ID
            $currentUserId = $this->getCurrentUserId();
            
            // 使用全局配置处理文件上传
            $filename = $file->getOriginalName();
            $extension = $file->getOriginalExtension();
            
            // 验证文件类型和大小
            if (!FileUploadConfig::isAllowedExtension($extension)) {
                return json(['code' => 400, 'msg' => '不支持的文件类型', 'data' => null, 'timestamp' => time()]);
            }
            
            if ($file->getSize() > FileUploadConfig::getMaxSize()) {
                return json(['code' => 400, 'msg' => '文件大小超过限制', 'data' => null, 'timestamp' => time()]);
            }
            
            // 生成安全的文件名
            $newFilename = FileUploadConfig::generateSafeFileName($filename);
            
            // 获取文件存储路径
            $savePath = FileUploadConfig::getStoragePath('article', 'disk');
            
            // 确保目录存在
            FileUploadConfig::ensureDirectoryExists($savePath);
            
            // 移动文件
            $file->move(public_path($savePath), $newFilename);
            $filePath = $savePath . '/' . $newFilename;
            
            // 确保路径使用正斜杠，避免Windows系统下的反斜杠问题
            $filePath = str_replace('\\', '/', $filePath);
            
            // 获取移动后的文件大小 - 修复Windows路径问题
            $fullFilePath = str_replace('\\', '/', public_path($filePath));
            // 确保路径末尾没有多余的斜杠
            $fullFilePath = rtrim($fullFilePath, '/');
            $fileSize = filesize($fullFilePath);
            
            // 保存到数据库
            $fileData = [
                'filename' => $newFilename,
                'filepath' => $filePath,
                'filesize' => $fileSize,
                'fileext' => $extension,
                'mimetype' => $file->getOriginalMime(),
                'name' => $filename,
                'module' => 'article',
                'action' => 'disk',
                'use' => '知识笔记附件',
                'user_id' => $currentUserId,
                'admin_id' => $currentUserId, // 修复：使用当前用户ID而不是0
                'audit_time' => time(), // 添加审核时间
                'uploadip' => $request->ip(),
                'create_time' => time(),
                'status' => 1,
                'download' => 0,
                'group_id' => 0,
                'delete_time' => 0,
                'sha1' => sha1_file($fullFilePath),
                'md5' => md5_file($fullFilePath)
            ];
            
            $fileId = Db::name('file')->insertGetId($fileData);
            
            // 返回符合项目规范的响应格式
            return json([
                'code' => 0, 
                'msg' => '上传附件成功', 
                'data' => [
                    'id' => $fileId,
                    'filename' => $newFilename,
                    'filepath' => $filePath,
                    'filesize' => $fileSize,
                    'fileext' => $extension,
                    'mimetype' => $file->getOriginalMime(),
                    'name' => $filename,
                    'module' => 'article',
                    'action' => 'disk',
                    'use' => '知识笔记附件',
                    'user_id' => $currentUserId,
                    'admin_id' => $currentUserId,
                    'audit_time' => time(),
                    'uploadip' => $request->ip(),
                    'create_time' => time(),
                    'status' => 1,
                    'download' => 0,
                    'group_id' => 0,
                    'delete_time' => 0,
                    'sha1' => sha1_file($fullFilePath),
                    'md5' => md5_file($fullFilePath)
                ],
                'timestamp' => time()
            ]);
            
        } catch (\Exception $e) {
            // 记录错误日志
            Log::error('文件上传失败: ' . $e->getMessage());
            
            // 返回错误信息
            return json(['code' => 500, 'msg' => '文件上传失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }
    
    /**
     * 移除附件
     */
    public function removeAttachment(RequestObject $request)
    {
        $noteId = $request->param('note_id');
        $fileId = $request->param('attachment_id');
        
        if (empty($noteId) || empty($fileId)) {
            return json(['code' => 400, 'msg' => '笔记ID和附件ID不能为空']);
        }
        
        try {
            // 查询文件信息
            $file = Db::name('file')
                ->where('id', '=', $fileId)
                ->where('group_id', '=', $noteId)
                ->where('module', '=', 'article')
                ->find();
            
            if (!$file) {
                return json(['code' => 404, 'msg' => '附件不存在或不属于该笔记']);
            }
            
            // 删除文件
            Filesystem::disk('public')->delete($file['path']);
            
            // 删除文件记录
            Db::name('file')
                ->where('id', '=', $fileId)
                ->delete();
            
            return json(['code' => 0, 'msg' => '移除附件成功']);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '移除附件失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 下载附件
     */
    public function downloadAttachment(RequestObject $request)
    {
        $fileId = $request->param('id');
        
        if (empty($fileId)) {
            return json(['code' => 400, 'msg' => '文件ID不能为空']);
        }
        
        try {
            // 查询文件信息
            $file = Db::name('file')
                ->where('id', '=', $fileId)
                ->where('delete_time', '=', 0)
                ->find();
            
            if (!$file) {
                return json(['code' => 404, 'msg' => '文件不存在或已删除']);
            }
            
            // 构建文件完整路径
            // 兼容性处理：确保filepath以/开头
            $filepath = $file['filepath'];
            if (substr($filepath, 0, 1) !== '/') {
                $filepath = '/' . $filepath;
            }
            $filePath = app()->getRootPath() . 'public' . $filepath;
            
            // 检查文件是否存在
            if (!file_exists($filePath)) {
                return json(['code' => 404, 'msg' => '文件不存在']);
            }
            
            // 更新下载次数
            Db::name('file')
                ->where('id', '=', $fileId)
                ->inc('download');
            
            // 获取文件内容
            $fileContent = file_get_contents($filePath);
            
            // 设置响应头
            $response = response($fileContent, 200, [
                'Content-Type' => $file['mimetype'],
                'Content-Disposition' => 'attachment; filename="' . $file['name'] . '"',
                'Content-Length' => $file['filesize'],
                'Cache-Control' => 'no-cache, must-revalidate',
                'Pragma' => 'no-cache',
                'Expires' => '0'
            ]);
            
            return $response;
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '下载文件失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 预览附件
     */
    public function previewAttachment(RequestObject $request)
    {
        $fileId = $request->param('file_id');
        
        if (empty($fileId)) {
            return json(['code' => 400, 'msg' => '文件ID不能为空', 'data' => null, 'timestamp' => time()]);
        }
        
        try {
            // 查询文件信息
            $file = Db::name('file')
                ->where('id', '=', $fileId)
                ->where('delete_time', '=', 0)
                ->find();
            
            if (!$file) {
                return json(['code' => 404, 'msg' => '文件不存在或已删除', 'data' => null, 'timestamp' => time()]);
            }
            
            // 构建文件完整路径
            $filepath = $file['filepath'];
            if (substr($filepath, 0, 1) !== '/') {
                $filepath = '/' . $filepath;
            }
            $filePath = app()->getRootPath() . 'public' . $filepath;
            
            // 检查文件是否存在
            if (!file_exists($filePath)) {
                return json(['code' => 404, 'msg' => '文件不存在', 'data' => null, 'timestamp' => time()]);
            }
            
            // 更新下载次数
            Db::name('file')
                ->where('id', '=', $fileId)
                ->inc('download');
            
            // 获取文件内容
            $fileContent = file_get_contents($filePath);
            
            // 获取MIME类型
            $mimeType = $file['mimetype'];
            
            // 处理中文文件名编码
            $fileName = $file['name'];
            $encodedFileName = $fileName;
            if (preg_match('/[\x80-\xff]/', $fileName)) {
                // 包含中文，使用RFC 3986标准编码
                $encodedFileName = 'UTF-8\'\'' . rawurlencode($fileName);
            }
            
            // 设置Content-Disposition头为inline，表示在浏览器中直接显示
            $contentDisposition = 'inline; filename="' . $fileName . '"; filename*=UTF-8\'\'' . rawurlencode($fileName);
            
            // 创建响应对象
            $response = response($fileContent, 200, [
                'Content-Type' => $mimeType,
                'Content-Disposition' => $contentDisposition,
                'Content-Length' => $file['filesize'],
                'Cache-Control' => 'max-age=3600, must-revalidate',
                'Pragma' => 'public',
                'Access-Control-Allow-Origin' => '*',
                'Access-Control-Allow-Headers' => 'Content-Type, Content-Disposition, Authorization',
                'Access-Control-Expose-Headers' => 'Content-Disposition'
            ]);
            
            return $response;
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '预览文件失败: ' . $e->getMessage(), 'data' => null, 'timestamp' => time()]);
        }
    }
    
    /**
     * 分享笔记
     */
    public function share(RequestObject $request)
    {
        $param = $request->param();
        $articleId = $param['id'];
        $userIds = $param['user_ids'] ?? '';
        $departmentIds = $param['department_ids'] ?? '';
        
        if (empty($articleId)) {
            return json(['code' => 400, 'msg' => '笔记ID不能为空']);
        }
        
        if (empty($userIds) && empty($departmentIds)) {
            return json(['code' => 400, 'msg' => '请选择要分享的用户或部门']);
        }
        
        try {
            // 验证笔记是否存在
            $articleExists = Db::name('article')
                ->where('id', '=', $articleId)
                ->where('delete_time', '=', 0)
                ->count() > 0;
            
            if (!$articleExists) {
                return json(['code' => 404, 'msg' => '笔记不存在或已删除']);
            }
            
            // 检查article_access表是否存在，如果不存在则创建
            $hasTable = Db::query("SHOW TABLES LIKE 'article_access'");
            if (empty($hasTable)) {
                try {
                    // 创建article_access表
                    Db::execute("CREATE TABLE `article_access` (
                      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
                      `article_id` int(11) NOT NULL DEFAULT '0' COMMENT '文章ID',
                      `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户ID',
                      `department_id` int(11) NOT NULL DEFAULT '0' COMMENT '部门ID',
                      `type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '类型:1用户,2部门',
                      `create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
                      PRIMARY KEY (`id`),
                      INDEX `idx_article_id` (`article_id`),
                      INDEX `idx_user_id` (`user_id`),
                      INDEX `idx_department_id` (`department_id`),
                      INDEX `idx_type` (`type`)
                    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='文章访问权限表';
                    ");
                } catch (\Exception $e) {
                    return json(['code' => 500, 'msg' => '创建数据库表失败: ' . $e->getMessage()]);
                }
            }
            
            // 开启事务
            Db::startTrans();
            
            try {
                // 删除原有的访问权限记录
                Db::name('article_access')
                    ->where('article_id', '=', $articleId)
                    ->delete();
                
                // 添加用户访问权限
                if (!empty($userIds)) {
                    $userIdArray = array_filter(explode(',', $userIds));
                    foreach ($userIdArray as $userId) {
                        if (!empty($userId)) {
                            Db::name('article_access')->insert([
                                'article_id' => $articleId,
                                'user_id' => (int)$userId,
                                'type' => 1, // 用户类型
                                'create_time' => time()
                            ]);
                        }
                    }
                }
                
                // 添加部门访问权限
                if (!empty($departmentIds)) {
                    $deptIdArray = array_filter(explode(',', $departmentIds));
                    foreach ($deptIdArray as $deptId) {
                        if (!empty($deptId)) {
                            Db::name('article_access')->insert([
                                'article_id' => $articleId,
                                'department_id' => (int)$deptId,
                                'type' => 2, // 部门类型
                                'create_time' => time()
                            ]);
                        }
                    }
                }
                
                // 注意：article表中没有status字段，所以不更新分享状态
                // 分享状态通过article_access表中的记录来维护
                
                // 提交事务
                Db::commit();
                
                return json(['code' => 0, 'msg' => '分享笔记成功']);
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '分享笔记失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 取消分享笔记
     */
    public function unshare()
    {
        $id = Request::param('id');
        
        if (empty($id)) {
            return json(['code' => 400, 'msg' => '笔记ID不能为空']);
        }
        
        try {
            // 检查article_access表是否存在
            $hasTable = Db::query("SHOW TABLES LIKE 'article_access'");
            if (empty($hasTable)) {
                return json(['code' => 501, 'msg' => '取消分享功能暂时不可用，因为缺少必要的数据库表']);
            }
            
            // 开启事务
            Db::startTrans();
            
            try {
                // 删除所有访问权限记录
                Db::name('article_access')
                    ->where('article_id', '=', $id)
                    ->delete();
                
                // 更新文章的分享状态
                // 注意：article表中没有status字段，所以不更新分享状态
                // 分享状态通过article_access表中的记录来维护
                
                // 提交事务
                Db::commit();
                
                return json(['code' => 0, 'msg' => '取消分享成功']);
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '取消分享失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 获取可分享用户列表
     */
    public function shareableUsers()
    {
        try {
            // 查询所有用户
            $users = Db::name('admin')
                ->field('id, name')
                ->where('status', '=', 1) // 只查询状态正常的用户
                ->select()
                ->toArray();
            
            return json(['code' => 0, 'msg' => 'success', 'data' => $users]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '获取用户列表失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 获取可分享部门列表
     */
    public function shareableDepartments()
    {
        try {
            // 查询所有部门，使用title字段并别名为name以保持前端兼容性
            $departments = Db::name('department')
                ->field('id, title as name')
                ->where('status', '=', 1) // 只查询状态正常的部门
                ->select()
                ->toArray();
            
            return json(['code' => 0, 'msg' => 'success', 'data' => $departments]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '获取部门列表失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 关联附件到笔记
     */
    public function attachFilesToNote()
    {
        // 使用post方法获取参数，确保可以正确获取POST请求中的参数
        $noteId = Request::post('note_id', 0);
        // 如果没有获取到note_id，则尝试获取article_id
        if (empty($noteId)) {
            $noteId = Request::post('article_id', 0);
        }
        // 获取file_ids参数
        $fileIds = Request::post('file_ids', '');
        
        // 也尝试通过param方法获取，确保兼容性
        if (empty($noteId)) {
            $noteId = Request::param('note_id', 0);
            if (empty($noteId)) {
                $noteId = Request::param('article_id', 0);
            }
        }
        if (empty($fileIds)) {
            $fileIds = Request::param('file_ids', '');
        }
        
        if (empty($noteId)) {
            return json(['code' => 400, 'msg' => '笔记ID不能为空']);
        }
        
        if (empty($fileIds)) {
            return json(['code' => 0, 'msg' => '没有附件需要关联']);
        }
        
        try {
            // 开启事务
            Db::startTrans();
            
            try {
                // 更新文件记录，关联到笔记
                $fileIdArray = array_filter(explode(',', $fileIds));
                foreach ($fileIdArray as $fileId) {
                    if (!empty($fileId)) {
                        Db::name('file')
                            ->where('id', '=', (int)$fileId)
                            ->where('group_id', '=', 0) // 只更新未关联的文件
                            ->update([
                                'group_id' => $noteId,
                                'create_time' => time()
                            ]);
                    }
                }
                
                // 获取article表当前的file_ids字段值
                $article = Db::name('article')->where('id', '=', $noteId)->find();
                if ($article) {
                    $currentFileIds = $article['file_ids'] ?? '';
                    
                    // 合并现有file_ids和新的file_ids，并去重
                    $allFileIds = '';
                    if (!empty($currentFileIds)) {
                        $existingIds = array_filter(explode(',', $currentFileIds));
                        $allFileIds = implode(',', array_unique(array_merge($existingIds, $fileIdArray)));
                    } else {
                        $allFileIds = $fileIds;
                    }
                    
                    // 更新article表的file_ids字段
                    Db::name('article')
                        ->where('id', '=', $noteId)
                        ->update(['file_ids' => $allFileIds]);
                }
                
                // 提交事务
                Db::commit();
                
                return json(['code' => 0, 'msg' => '附件关联成功']);
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '附件关联失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 搜索笔记
     */
    public function search()
    {
        $param = Request::param();
        $keywords = $param['keywords'] ?? '';
        
        if (empty($keywords)) {
            return json(['code' => 400, 'msg' => '搜索关键词不能为空']);
        }
        
        try {
            // 构建查询条件
            $where = [];
            $where[] = ['a.delete_time', '=', 0];
            // 移除type字段查询条件，因为oa_article表中没有type字段
            $where[] = ['a.admin_id', '=', 1]; // 默认用户ID，实际应根据登录用户确定
            $where[] = [
                ['a.name', 'like', '%' . trim($keywords) . '%'],
                ['a.content', 'like', '%' . trim($keywords) . '%'],
                'OR'
            ];
            
            // 查询笔记列表
            $list = Db::name('article')
                ->alias('a')
                ->join('admin ad', 'a.admin_id = ad.id', 'LEFT')
                ->field('a.id, a.name as title, a.content, a.create_time, a.update_time, ad.name as author')
                ->where($where)
                ->order('a.update_time', 'desc')
                ->limit(20) // 限制搜索结果数量
                ->select()
                ->each(function($item) {
                    // 格式化时间
                    $item['create_time'] = date('Y-m-d H:i', $item['create_time']);
                    $item['update_time'] = date('Y-m-d H:i', $item['update_time']);
                    // 暂时设置为未分享，因为article_access表不存在
                    $item['is_shared'] = false;
                    // 初始化为空数组
                    $item['shared_users'] = [];
                    $item['shared_departments'] = [];
                    $item['attachments'] = [];
                    return $item;
                });
            
            return json(['code' => 0, 'msg' => 'success', 'data' => $list]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '搜索笔记失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 记录笔记操作日志
     */
    private function writeNoteLog($userId, $articleId, $action, $description)
    {
        try {
            $logData = [
                'user_id' => $userId,
                'article_id' => $articleId,
                'action' => $action,
                'description' => $description,
                'ip' => Request::ip(),
                'user_agent' => Request::header('User-Agent'),
                'create_time' => time()
            ];
            
            Db::name('article_log')->insert($logData);
        } catch (\Exception $e) {
            // 记录日志失败不影响主流程
            // 可以记录到系统日志
        }
    }
    
    /**
     * 获取当前登录用户ID
     */
    private function getCurrentUserId()
    {
        // 从请求中获取用户ID（由JWT中间件设置）
        $userId = $this->request->userId ?? 0;
        if ($userId > 0) {
            return $userId;
        }
        
        // 如果中间件没有设置userId，尝试从Authorization头获取JWT token
        $authHeader = Request::header('Authorization');
        if ($authHeader) {
            $token = str_replace('Bearer ', '', $authHeader);
            $userId = $this->verifyJwtToken($token);
            if ($userId) {
                return $userId;
            }
        }
        
        // 如果JWT验证失败，尝试从Token参数获取（兼容原系统）
        $token = Request::param('token') ?: Request::header('Token');
        if ($token) {
            $userId = $this->verifyJwtToken($token);
            if ($userId) {
                return $userId;
            }
            
            // 兼容原系统的token格式
            $legacyUserId = $this->verifyLegacyToken($token);
            return $legacyUserId;
        }
        
        return 0;
    }
    
    /**
     * 获取当前用户信息
     */
    private function getCurrentUser()
    {
        $userId = $this->getCurrentUserId();
        return User::find($userId);
    }
    
    /**
     * 获取当前用户部门ID
     */
    private function getCurrentUserDepartmentId()
    {
        $user = $this->getCurrentUser();
        return $user ? $user->getAttr('did') : 0;
    }
    
    /**
     * 还原笔记
     */
    public function restore()
    {
        $id = Request::param('id');
        $userId = $this->getCurrentUserId();
        
        if (empty($id)) {
            return json(['code' => 400, 'msg' => '笔记ID不能为空']);
        }
        
        try {
            // 验证笔记是否存在且属于当前用户
            $article = Db::name('article')
                ->where('id', '=', $id)
                ->where('admin_id', '=', $userId)
                ->where('delete_time', '>', 0)
                ->find();
            
            if (!$article) {
                return json(['code' => 404, 'msg' => '笔记不存在或不属于当前用户']);
            }
            
            // 开启事务
            Db::startTrans();
            
            try {
                // 还原笔记
                Db::name('article')
                    ->where('id', '=', $id)
                    ->update([
                        'delete_time' => 0,
                        'update_time' => time()
                    ]);
                
                // 清除原有的共享设置 - 由于表中没有status字段，暂时注释掉
                // Db::name('article')
                //     ->where('id', '=', $id)
                //     ->update(['status' => 0]);
                
                // 提交事务
                Db::commit();
                
                // 记录操作日志
                $this->writeNoteLog($userId, $id, 'restore', '还原笔记');
                
                return json(['code' => 0, 'msg' => '还原笔记成功']);
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '还原笔记失败: ' . $e->getMessage()]);
        }
    }
    
    /**
     * 彻底删除笔记
     */
    public function forceDelete()
    {
        $id = Request::param('id');
        $userId = $this->getCurrentUserId();
        
        if (empty($id)) {
            return json(['code' => 400, 'msg' => '笔记ID不能为空']);
        }
        
        try {
            // 验证笔记是否存在且属于当前用户
            $article = Db::name('article')
                ->where('id', '=', $id)
                ->where('admin_id', '=', $userId)
                ->where('delete_time', '>', 0)
                ->find();
            
            if (!$article) {
                return json(['code' => 404, 'msg' => '笔记不存在或不属于当前用户']);
            }
            
            // 开启事务
            Db::startTrans();
            
            try {
                // 删除笔记关联的附件
                $fileIds = Db::name('file')
                    ->where('group_id', '=', $id)
                    ->where('module', '=', 'article')
                    ->column('id');
                
                if (!empty($fileIds)) {
                    // 删除文件记录
                    Db::name('file')
                        ->where('id', 'in', $fileIds)
                        ->delete();
                }
                
                // 彻底删除笔记
                Db::name('article')
                    ->where('id', '=', $id)
                    ->delete();
                
                // 提交事务
                Db::commit();
                
                // 记录操作日志
                $this->writeNoteLog($userId, $id, 'force_delete', '彻底删除笔记');
                
                return json(['code' => 0, 'msg' => '彻底删除笔记成功']);
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '彻底删除笔记失败: ' . $e->getMessage()]);
        }
    }
}